Skip to main content

etcd pressure test

对 etcd 进行压力测试是评估其性能、稳定性和在高负载下的表现的重要步骤。以下是一个详细的指南,介绍如何使用 etcd 自带的工具(如 benchmark)或其他方法来进行压力测试,并分析结果。


前提条件

  1. etcd 已部署

    • 确保你已经搭建了一个 etcd 集群(单节点或多节点均可)。例如,使用之前的配置(IP: 192.168.30.189, 192.168.24.192, 192.168.28.4)。
    • 集群正常运行,可以通过 etcdctl member listetcdctl endpoint health 验证。
  2. 工具准备

    • etcdctl:etcd 自带的管理工具,用于基本操作和验证。
    • benchmark:etcd 提供的压力测试工具,位于 etcd 源码的 tools/benchmark 目录下。
    • 可选工具:fio(测试磁盘性能)、Prometheus(监控指标)。
  3. 环境要求

    • 确保网络稳定,节点间通信正常。
    • 磁盘性能良好(建议 SSD,WAL 文件的 fdatasync 延迟应低于 10ms)。

步骤 1:获取 benchmark 工具

etcd 的 benchmark 工具不在二进制发行版中,需要从源码编译:

  1. 下载源码

    git clone https://github.com/etcd-io/etcd.git
    cd etcd/tools/benchmark
  2. 编译

    go build -o benchmark main.go
  3. 移动到可执行路径

    sudo mv benchmark /usr/local/bin/
  4. 验证

    benchmark --help

    如果输出帮助信息,说明编译成功。


步骤 2:设计压力测试场景

etcd 的性能主要体现在读写操作上,因此需要测试以下场景:

  • 写性能:模拟大量 PUT 请求。
  • 读性能:测试线性读(linearizable)和序列化读(serializable)。
  • 混合负载:读写同时进行。
  • 高并发:多个客户端和连接。

以下是针对你的集群(192.168.30.189:2379, 192.168.24.192:2379, 192.168.28.4:2379)的测试示例。

测试 1:写性能(PUT)

测试不同客户端数量下的写性能:

benchmark --endpoints=192.168.30.189:2379,192.168.24.192:2379,192.168.28.4:2379 \
--conns=100 \
--clients=100 \
put --key-size=10 \
--sequential-keys \
--total=100000 \
--val-size=256
  • --conns:连接数。
  • --clients:客户端数。
  • --total:总请求数。
  • --key-size--val-size:键值大小。

测试 2:读性能(RANGE)

测试线性读和序列化读:

  • 线性读(强一致性):

    benchmark --endpoints=192.168.30.189:2379,192.168.24.192:2379,192.168.28.4:2379 \
    --conns=100 \
    --clients=100 \
    range /test-key \
    --consistency=l \
    --total=100000
  • 序列化读(可能返回旧数据,性能更高):

    benchmark --endpoints=192.168.30.189:2379,192.168.24.192:2379,192.168.28.4:2379 \
    --conns=100 \
    --clients=100 \
    range /test-key \
    --consistency=s \
    --total=100000

测试 3:混合负载

模拟读写混合场景:

benchmark --endpoints=192.168.30.189:2379,192.168.24.192:2379,192.168.28.4:2379 \
--conns=100 \
--clients=50 \
put --key-size=10 \
--sequential-keys \
--total=50000 \
--val-size=256 \
& \
benchmark --endpoints=192.168.30.189:2379,192.168.24.192:2379,192.168.28.4:2379 \
--conns=100 \
--clients=50 \
range /test-key \
--consistency=l \
--total=50000

步骤 3:运行测试并收集结果

  1. 运行测试
    在测试机上执行上述命令,记录输出。输出通常包括:

    • QPS(每秒查询率):吞吐量。
    • 平均延迟(ms):响应时间。
    • 错误数:请求失败次数。

    示例输出:

    Total: 100000, QPS: 7309, Avg Latency: 27ms, Errors: 0
  2. 监控指标

    • 使用 etcdctl check perf 检查集群性能:

      etcdctl --endpoints=192.168.30.189:2379 check perf
    • 通过 /metrics 端点收集 Prometheus 指标:

      curl http://192.168.30.189:2379/metrics

      关注 etcd_disk_wal_fsync_duration_seconds(WAL 同步延迟)和 etcd_server_leader_changes_seen_total(领导者变更次数)。

  3. 磁盘性能(可选):
    使用 fio 测试磁盘延迟:

    fio --name=etcd-test --rw=write --bs=4k --size=1G --numjobs=1 --iodepth=32 --runtime=60 --time_based --fdatasync=1 --directory=/var/lib/etcd

    检查 99 分位的 fdatasync 延迟,确保低于 10ms。


步骤 4:分析结果

  • 写性能
    • 单节点可能达到 3万-4万 QPS,多节点集群受 Raft 一致性限制,通常在 7千-1万 QPS。
    • 如果 QPS 较低,检查磁盘延迟或网络 RTT。
  • 读性能
    • 序列化读 QPS 高于线性读(可能达 7万+ QPS),但一致性较弱。
    • 线性读受集群 quorum 影响,QPS 较低(5万左右)。
  • 异常情况
    • 如果出现 etcdserver: too many requests,说明 Raft 提交索引超前过多,需减少并发或优化磁盘。
    • 领导者频繁切换(leader_changes_seen_total 增加),检查网络稳定性。

优化建议

  1. 磁盘优化
    • 使用 SSD,确保 WAL 文件的 fdatasync 延迟 < 10ms。
    • 将 snapshot 和 WAL 分到不同磁盘。
  2. 网络优化
    • 降低节点间 RTT(建议同数据中心部署)。
    • 使用负载均衡器分担客户端请求。
  3. 配置调整
    • 增大 --heartbeat-interval--election-timeout(如 100ms 和 1000ms),减少领导者切换。
    • 调整 --max-request-bytes 限制请求大小。
  4. 资源隔离
    • 确保 etcd 独占节点,避免与其他服务竞争 CPU/磁盘。

示例测试脚本

以下是一个自动化测试脚本:

#!/bin/bash
ENDPOINTS="192.168.30.189:2379,192.168.24.192:2379,192.168.28.4:2379"
echo "测试写性能..."
benchmark --endpoints=$ENDPOINTS --conns=100 --clients=100 put --key-size=10 --sequential-keys --total=100000 --val-size=256

echo "测试线性读性能..."
benchmark --endpoints=$ENDPOINTS --conns=100 --clients=100 range /test-key --consistency=l --total=100000

echo "测试序列化读性能..."
benchmark --endpoints=$ENDPOINTS --conns=100 --clients=100 range /test-key --consistency=s --total=100000

运行:

chmod +x test.sh
./test.sh

如果测试中遇到具体问题(如性能瓶颈、错误日志),请提供详细信息,我可以帮你进一步分析和优化!